package client

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	"os"
)

type Config struct {
	Remote   string
	Local    string
	Username string
	Password string
	Mode     string
}

type HttpRequestData struct {
	Method string
	Header http.Header
	Body   []byte
	Url    string
}

type HttpResponseData struct {
	Status int
	Header http.Header
	Body   []byte
}

var (
	config = Config{}
)

func checkErrorStack(info string, err error) bool {
	if err != nil {
		fmt.Println(info + ": " + err.Error())
		return false
	}
	return true
}

func readFromRemote(conn *net.Conn) {
	client := &http.Client{}
	for {
		fmt.Println("pending`````")
		readBuffer := make([]byte, 4096)
		length, err := (*conn).Read(readBuffer)
		// fmt.Println("recved")
		if err != nil {
			fmt.Println(err.Error())
			(*conn).Close()
			os.Exit(0)
		}
		go sendToLocalServer(readBuffer[:length], client, conn)
	}
}

// func sendToRemote(data []byte, conn *net.Conn) {

// }

func sendToLocalServer(recv []byte, httpClient *http.Client, conn *net.Conn) {
	// var reqData http.Request
	// reqBuf := bytes.NewBuffer(recv)
	// err := binary.Read(reqBuf, binary.LittleEndian, &reqData)
	reqData := HttpRequestData{}
	err := json.Unmarshal(recv, &reqData)
	if err != nil {
		log.Println(err.Error())
	}

	// path := string([]rune(reqData.URL.Path)[5:])
	// fmt.Println(path)
	// path = path[strings.Index(path, "/")+1:]
	url := config.Mode + "://" + config.Local + reqData.Url
	request, _ := http.NewRequest(reqData.Method, url, bytes.NewReader(reqData.Body))
	request.Header = reqData.Header
	response, err := httpClient.Do(request)
	if err != nil {
		log.Fatal(err.Error())
	}

	respData := HttpResponseData{}
	respBody, err := ioutil.ReadAll(response.Body)
	// fmt.Println(string(respBody))
	respData.Body = respBody
	respData.Header = response.Header
	respData.Status = response.StatusCode

	// buf := new(bytes.Buffer)
	// err = binary.Write(buf, binary.LittleEndian, response)
	dataSend, err := json.Marshal(respData)
	if err != nil {
		fmt.Println("jsonfy failed:", err)
	}
	(*conn).Write(dataSend)
}

func login(conn *net.Conn) (result bool) {
	loginInfo := `{"username": "` + config.Username + `", "password": "` + config.Password + `"}`

	(*conn).Write([]byte(loginInfo))
	buffer := make([]byte, 1024)
	l, err := (*conn).Read(buffer)
	if err != nil {
		log.Fatal(err.Error())
	}
	if string(buffer[:l]) == "succeed" {
		return true
	}
	fmt.Println(string(buffer))
	return false
}

// RunClient : 运行在私有局域网中的客户端
func RunClient(conf Config) {
	// err := readConfig("./config.json", config)
	config = conf
	connRemote, err := net.Dial("tcp", config.Remote)
	if err != nil {
		fmt.Println(err.Error())
		os.Exit(1)
	}
	result := login(&connRemote)
	if result {
		fmt.Println("wait for msg")
		readFromRemote(&connRemote)
	} else {
		connRemote.Close()
	}
}
